home *** CD-ROM | disk | FTP | other *** search
- // miditrim written by Günter Nagler 1996 (gnagler@ihm.tu-graz.ac.at)
- #include "midiio.hpp"
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
-
- static char* version = "miditrim v1.1 by Günter Nagler (" __DATE__ ")";
-
- char* input = 0;
- char* output = 0;
-
- int trimend = 0;
- int trimstart = 0;
-
- class MidiScanStartEnd : public MidiRead
- {
- public:
- MidiScanStartEnd(char* name);
-
- virtual void track(int trackno, long length, int channel);
-
- virtual void event(int what, int len = 0, unsigned char* data = 0);
- virtual void noteon(int channel, int note, int vel);
- virtual void noteoff(int channel, int note, int vel);
- virtual void end();
- virtual void meta(int what, int len, unsigned char* data);
-
- virtual void error(const char* msg);
- virtual void warning(const char* msg);
-
- virtual void percent(int perc);
-
- long firstevent_, lastevent_;
- long firstnote_, lastnote_;
- long end_;
-
- protected:
- void eventtime(int noteev = 0);
-
- unsigned char noteplaying_[16][128];
- };
-
- void MidiScanStartEnd::eventtime(int noteev)
- {
- if (firstevent_ < 0 || getcurunit() < firstevent_)
- firstevent_ = getcurunit();
- if (lastevent_ < 0 || getcurunit() > lastevent_)
- lastevent_ = getcurunit();
- if (noteev)
- {
- if (firstnote_ < 0 || getcurunit() < firstnote_)
- firstnote_ = getcurunit();
- if (lastnote_ < 0 || getcurunit() > lastnote_)
- lastnote_ = getcurunit();
- }
- if (end_ < 0 || getcurunit() > end_)
- end_ = getcurunit();
- }
-
- MidiScanStartEnd::MidiScanStartEnd(char* name) : MidiRead(name)
- {
- options_ = OPTION_NOCONTROLS + OPTION_NOSYSEVENTS +
- OPTION_NOPOLYEVENTS + OPTION_NOCONTROLEVENTS +
- OPTION_NOPROGRAMEVENTS + OPTION_NOAFTERTOUCHEVENTS +
- OPTION_NOPITCHBENDEVENTS;
-
- firstevent_ = -1;
- lastevent_ = -1;
- firstnote_ = -1;
- lastnote_ = -1;
- end_ = -1;
- }
-
- void MidiScanStartEnd::track(int trackno, long length, int channel)
- {
- for (int c = 0; c < 16; c++)
- for (int i = 0; i < 128; i++)
- noteplaying_[c][i] = 0;
- }
-
- void MidiScanStartEnd::noteon(int channel, int note, int vel)
- {
- assert(channel >= 0 && channel <= 15);
- eventtime(1);
- noteplaying_[channel][note] = 1;
- }
-
- void MidiScanStartEnd::noteoff(int channel, int note, int vel)
- {
- assert(channel >= 0 && channel <= 15);
- if (noteplaying_[channel][note])
- eventtime(1);
- else
- eventtime(0); // not necessary note event
- noteplaying_[channel][note] = 0;
- }
-
- void MidiScanStartEnd::end() // end of track
- {
- // not an event
- if (end_ < 0 || getcurunit() > end_)
- end_ = getcurunit();
- }
-
- void MidiScanStartEnd::meta(int what, int len, unsigned char* data)
- {
- eventtime();
- }
-
- void MidiScanStartEnd::event(int what, int len, unsigned char* data)
- {
- eventtime();
- }
-
- void MidiScanStartEnd::percent(int perc)
- {
- fprintf(stderr, "%-3d%%\r", perc);
- }
-
- void MidiScanStartEnd::error(const char* msg)
- {
- printf("Error: %s\n", msg);
- exit(1);
- }
-
- void MidiScanStartEnd::warning(const char* msg)
- {
- printf("Warning: %s\n", msg);
- }
-
-
- class MidiTrim : public MidiCopy
- {
- public:
- MidiTrim(char* name);
-
- virtual void track(int trackno, long length, int channel);
-
- virtual void event(int what, int len, unsigned char* data);
-
- virtual void time(unsigned long ticks);
-
- virtual void error(const char* msg);
- virtual void warning(const char* msg);
-
-
- virtual void percent(int perc);
-
- unsigned long trimuntil_, trimfrom_;
- };
-
- MidiTrim::MidiTrim(char* name) : MidiCopy(name)
- {
- options_ = OPTION_NOCONTROLS + OPTION_NOSYSEVENTS +
- OPTION_NOPOLYEVENTS + OPTION_NOCONTROLEVENTS +
- OPTION_NOPROGRAMEVENTS + OPTION_NOAFTERTOUCHEVENTS +
- OPTION_NOPITCHBENDEVENTS + OPTION_NONOTEEVENTS;
- trimuntil_ = 0; trimfrom_ = 0xffffffffUL;
- }
-
- void MidiTrim::track(int trackno, long length, int channel)
- {
- MidiCopy::track(trackno, length, channel);
- }
-
- void MidiTrim::time(unsigned long ticks)
- {
- long curtime = getcurunit();
-
- if (ticks > 0)
- {
- if (curtime < trimuntil_)
- {
- if (curtime + ticks <= trimuntil_)
- {
- // remove full pause
- ticks = 0;
- curtime += ticks;
- }
- else
- {
- // remove pause between curtime and trimuntil only
- ticks = curtime + ticks - trimuntil_;
- curtime = trimuntil_;
- }
- }
- else if (curtime + ticks >= trimfrom_)
- {
- if (curtime >= trimfrom_)
- {
- // remove full pause
- ticks = 0;
- curtime += ticks;
- }
- else
- {
- // keep pause till trimfrom
- ticks = trimfrom_ - curunit_;
- curtime = trimfrom_;
- }
- }
- }
- MidiCopy::time(ticks);
- }
-
- void MidiTrim::event(int what, int len, unsigned char* data)
- {
- MidiCopy::event(what, len, data);
- }
-
- void MidiTrim::percent(int perc)
- {
- fprintf(stderr, "%-3d%%\r", perc);
- }
-
- void MidiTrim::error(const char* msg)
- {
- printf("Error: %s\n", msg);
- exit(1);
- }
-
- void MidiTrim::warning(const char* msg)
- {
- printf("Warning: %s\n", msg);
- }
-
- void usage()
- {
- printf("miditrim removes pauses at beginning and end of song\n");
- printf("usage: miditrim [-start] [-end] [-both] file.mid newfile.mid\n");
- printf("-version\tget program version\n");
- printf("-start\t\tremove pauses before first note in song is played\n");
- printf("-end\t\tremove pauses after last note in song has stopped\n");
- printf("-both\t\ttrim start and end of song (is default)\n");
- exit(1);
- }
-
- int main(int argc, char**argv)
- {
- argc--; argv++;
- while (argc > 0 && **argv == '-')
- {
- if (strncmp(*argv, "-version", 2) == 0)
- {
- fprintf(stderr, "%s\n", version);
- argc--; argv++;
- if (argc == 0)
- return 0;
- continue;
- }
- if (strncmp(*argv, "-start", 2) == 0)
- {
- trimstart = 1;
- argc--; argv++;
- continue;
- }
- if (strncmp(*argv, "-end", 2) == 0)
- {
- trimend = 1;
- argc--; argv++;
- continue;
- }
- if (strncmp(*argv, "-both", 2) == 0)
- {
- trimstart = trimend = 1;
- argc--; argv++;
- continue;
- }
- fprintf(stderr, "invalid option %s\n", *argv);
- argc--; argv++;
- usage();
- }
- if (argc < 1)
- usage();
-
- input = argv[0];
- if (argc >= 2)
- {
- output = argv[1];
- if (strcmp(input, output) == 0)
- {
- fprintf(stderr, "cannot convert midi to same file\n");
- return 1;
- }
- }
-
- if (!trimstart && !trimend)
- trimstart = trimend = 1; // default: trimboth
-
- MidiScanStartEnd midi(input);
- if (!midi.getf())
- {
- perror(input);
- return 1;
- }
- midi.run();
-
- if (argc == 1)
- {
- printf("File: %s\n", input);
- printf("first event: %ld\n", midi.firstevent_);
- printf("last event: %ld\n", midi.lastevent_);
- printf("first note: %ld\n", midi.firstnote_);
- printf("last note: %ld\n", midi.lastnote_);
- printf("end: %ld\n", midi.end_);
- if (midi.firstnote_ > 0)
- printf("pause 0-%ld could be trimmed.\n", midi.firstnote_);
- if (midi.lastnote_ < midi.end_)
- printf("pause %ld-%ld could be trimmed.\n", midi.lastnote_, midi.end_);
- }
-
- if (midi.firstnote_ == 0 && midi.lastnote_ == midi.end_)
- {
- printf("%s is already trimmed.\n", input);
- }
-
- if (argc == 1)
- return 0;
- MidiTrim midicopy(input);
- if (!midi.getf())
- {
- perror(input);
- return 1;
- }
-
- MidiWrite* write = new MidiWrite(output);
- if (!write)
- {
- fprintf(stderr, "out of memory\n");
- return 1;
- }
- if (!write->getf())
- {
- perror(output);
- return 1;
- }
- argc--; argv++;
-
- midicopy.setoutput(write);
-
- if (trimstart)
- midicopy.trimuntil_ = midi.firstnote_;
- else
- midicopy.trimuntil_ = 0;
-
- if (trimend)
- midicopy.trimfrom_ = midi.lastnote_;
- else
- midicopy.trimfrom_ = midi.lastevent_;
- if (!midicopy.run())
- fprintf(stderr, "%s: midi read error at %04lX\n", input, midi.getpos());
- else
- printf("output written to %s\n", output);
- delete write;
- return 0;
- }
-